package Array.BinarySearch;//输入整数数组 arr ，找出其中最小的 k 个数。例如，输入4、5、1、6、2、7、3、8这8个数字，则最小的4个数字是1、2、3、4。
//
// 
//
// 示例 1： 
//
// 输入：arr = [3,2,1], k = 2
//输出：[1,2] 或者 [2,1]
// 
//
// 示例 2： 
//
// 输入：arr = [0,1,2,1], k = 1
//输出：[0] 
//
// 
//
// 限制： 
//
// 
// 0 <= k <= arr.length <= 10000 
// 0 <= arr[i] <= 10000 
// 
// Related Topics 数组 分治 快速选择 排序 堆（优先队列） 👍 415 👎 0

import java.util.*;
//leetcode submit region begin(Prohibit modification and deletion)
class getLeastNumbers {


    /**
     * 快排定位 k-1
     *
     * */
    public int[] getLeastNumbers(int[] arr, int k) {
        if(k==0 || arr==null || arr.length==0){
            return new int[]{};
        }
        if(arr.length==k){
            return arr;
        }
        //利用快排，当快排的位置为k-1时前面的就是最小的
        find(arr,k-1,0, arr.length-1);
        int[] res = new int[k];
        for (int i = 0; i < k; i++) {
            res[i] = arr[i];
        }
        return res;
    }

    private void find(int[] arr, int k, int start, int end){
        if(start<=end){
            int index = quickSort(arr, start, end);
            if(index == k){
                return;
            }else if(index > k){
                find(arr, k, start, index-1);
            }else{
                find(arr, k, index+1,end);
            }
        }
    }

    private int quickSort(int[] arr, int start, int end){

        int priot = arr[start];
        int i = start;
        int j = end;
        while (i<j){
            while(i<j && arr[j] > priot){
                j--;
            }
            if(i<j){
                arr[i++] = arr[j];
            }
            while(i<j && arr[i] < priot){
                i++;
            }
            if(i<j){
                arr[j--] = arr[i];
            }

        }
        arr[i] = priot;
        return i; //定位的当前位置。
    }


    /**
     * 最大堆解决
     *
     * */
    public int[] getLeastNumbers1(int[] arr, int k) {

        if(k==0 || arr==null || arr.length==0){
            return new int[]{};
        }
        PriorityQueue<Integer> queue = new PriorityQueue<>((o1,o2)-> o2-o1);
        //最小的k个数构建大顶堆
        for(int i : arr){
            queue.offer(i);
            if(queue.size()>k){
                queue.poll();
            }
        }
        int[] res = new int[k];
        int index = 0;
        while(!queue.isEmpty()){
            res[index++] = queue.poll();
        }
        return res;

    }
}
//leetcode submit region end(Prohibit modification and deletion)
